using System;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
using System.Reflection;
using Meta;

namespace Meta.Editor {
	/// <summary>
	/// Summary description for LogInspector.
	/// </summary>
	class LogInspector : Meta.Inspector {
		class EventLog : ArrayList, IInspectable {
			public int MaxLogLength = 3000;

			public bool LogFull {
				get {
					return this.Count >= MaxLogLength;
				}
			}

			string IInspectable.InspectorName() {
				return "Execution Log";
			}

			InspectorField[] oldRenderCache=null;
			InspectorField[] renderCache=null;
			IList IInspectable.RenderForInspection() {
				if (renderCache==null) {
					renderCache = new InspectorField[Count];
					int start=0;
					if (oldRenderCache!=null) {
						start = oldRenderCache.Length;
						oldRenderCache.CopyTo(renderCache, 0);
					}
					for (int i=0; i<Count; i++) {
						renderCache[i] = new InspectorField(i.ToString(), this[i], Writer.SafeWriteToString(this[i], 100), false);
					}
				}
				return renderCache;
			}
			public void InvalidateCache(bool keepOld) {
				if (!keepOld)
					oldRenderCache = null;
				else if (renderCache!=null)
					oldRenderCache=renderCache;
				renderCache = null;
			}
			public override int Add(object value) {
				if (!LogFull) {
					InvalidateCache(true);
					return base.Add (value);
				} else
					return Count-1;
			}
			public override void Clear() {
				InvalidateCache(false);
				base.Clear();
			}
		}

		EventLog log;
		System.Windows.Forms.Timer updateTimer = new System.Windows.Forms.Timer();
		public LogInspector() : base(new EventLog()) {
			log = (EventLog)(realInspector.CurrentObject);
			mainMenu.Items.Add(new ToolStripMenuItem("Log", null,
                new ToolStripItem[] {
                    new ToolStripMenuItem("Clear log", null, new EventHandler(ClearLog),
                    Keys.Delete) }));
			updateTimer.Interval = 250;
			updateTimer.Tick += new EventHandler(ReallyUpdate);
		}

		protected override void OnClosing(System.ComponentModel.CancelEventArgs e) {
			updateTimer.Stop();
			base.OnClosing (e);
		}

		void ReallyUpdate(object sender, EventArgs e) {
			ReallyUpdate();
		}

		void ReallyUpdate() {
			updateTimer.Stop();
			realInspector.UpdateRendering();
		}

		void ScheduleUpdate() {
			if (!log.LogFull)
				updateTimer.Start();
		}

		public static bool InhibitLogReset=false;
		public void ClearLog(object sender, EventArgs e) {
			if (!InhibitLogReset) {
				log.Clear();
				ReallyUpdate();
				Refresh();
			}
		}
			
		public void Log(object o) {
			log.Add(o);
			ScheduleUpdate();
		}

		public void ClearRenderCache() {
			log.InvalidateCache(false);
		}
	}
}